//
//  Rectangle.cpp
//  Chart
//
//  Created by CaoJun on 13-5-22.
//
//

#include "Rectangle.h"

using namespace ytx;

Rectangle::Rectangle(): defaultSetting(RectangleOption())
{

}

Rectangle::Rectangle(YTXSize* size, RectangleOption rect){
    resize(size, rect);
}

Rectangle::Rectangle(const YTXSize & size){
    resize(size);
}

Rectangle::Rectangle(int width, int height, RectangleOption rect){
    resize(width, height, rect);
}

Rectangle::Rectangle(int width, int height){
    resize(width, height);
}

Rectangle::~Rectangle(){
    //    if (defaultSetting) {
    //        delete defaultSetting;
    //        defaultSetting = NULL;
    //    }
}

void Rectangle::resize(YTXSize* size, RectangleOption rect) {
    resize(size->width, size->height, rect);
}

void Rectangle::resize(const YTXSize & size) {
    resize(size.width, size.height);
}

void Rectangle::resize(int width, int height) {
    resize(width, height, this->defaultSetting);
}

void Rectangle::resize(int width, int height, RectangleOption rectangleOption) {
    RectangleOption rect;
    rect = this->defaultSetting =  RectangleOption(rectangleOption);
    if (width <= 0 || height <= 0) {
        return;
    }
    this->CanvasWidth = width;
    this->CanvasHeight = height;
    this->rounded = rect.rounded;

    float PADDING_TOP_MAX = CanvasWidth/0.5;
    float PADDING_BOTTOM_MAX= CanvasWidth/0.5;
    float PADDING_RIGHT_MAX = CanvasWidth/0.5;
    float PADDING_LEFT_MAX= CanvasWidth/0.5;

    this->paddingTop = (float) Tools::between(0, PADDING_TOP_MAX, rect.paddingTop);
    this->paddingRight = (float) Tools::between(0, PADDING_RIGHT_MAX, rect.paddingRight);
    this->paddingBottom = (float) Tools::between(0, PADDING_BOTTOM_MAX, rect.paddingBottom);
    this->paddingLeft = (float) Tools::between(0, PADDING_LEFT_MAX, rect.paddingLeft);

    SizeType::SizeType WidthType = getWidthType();
    SizeType::SizeType HeightType = getHeightType();

    switch (HeightType) {
        case SizeType::big:

            break;
        case SizeType::middle:

            break;
        case SizeType::small:

            break;
    }

    switch (WidthType) {
        case SizeType::big:

            break;
        case SizeType::middle:

            break;
        case SizeType::small:
            this->paddingRight = 5;
            break;
    }

    RectWidth = CanvasWidth - paddingLeft - paddingRight;
    RectHeight = CanvasHeight - paddingTop - paddingBottom;

    resetRowAndColumn(rect.row, rect.column);

    BeginX = paddingLeft;
    BeginY = paddingTop;

    EndX = BeginX + RectWidth;
    EndY = BeginY + RectHeight;
}

void Rectangle::changePaddingBottom(float bottomPadding)
{
    float PADDING_BOTTOM_MAX= CanvasHeight/0.5;
    this-> defaultSetting.paddingBottom = this->paddingBottom = (float) Tools::between(0, PADDING_BOTTOM_MAX, bottomPadding);
}

void Rectangle::changePaddingTop(float paddingTop)
{
    float PADDING_TOP_MAX= CanvasHeight/0.5;
    this-> defaultSetting.paddingTop = this->paddingTop = (float) Tools::between(0, PADDING_TOP_MAX, paddingTop);
}

SizeType::SizeType Rectangle::getWidthType() const {
    if (CanvasWidth <= 300)
        return SizeType::small;
    else if (CanvasWidth <= 400)
        return SizeType::middle;
    return SizeType::big;
}

SizeType::SizeType Rectangle::getHeightType() const {
    if (CanvasHeight <= 250)
        return SizeType::small;
    else if (CanvasHeight <= 320)
        return SizeType::middle;
    return SizeType::big;
}

void Rectangle::resetRowAndColumn(Rect row, Rect column){
    SizeType::SizeType WidthType = getWidthType();
    SizeType::SizeType HeightType = getHeightType();
    int r = 22, c = 10;

    switch (WidthType) {
        case SizeType::big:
            r = row.big == 0 ? 22 : row.big;
            break;
        case SizeType::middle:
            r =  row.middle == 0 ? 16 : row.middle;
            break;
        case SizeType::small:
            r = row.small == 0 ? 4 : row.small;
            break;
    }

    switch (HeightType) {
        case SizeType::big:
            c = column.big ==0 ? 10 : column.big;
            break;
        case SizeType::middle:
            c = column.middle == 0 ? 6 : column.middle;
            break;
        case SizeType::small:
            c = column.small ==0 ? 2 : column.small;
            break;
    }

    setColumn(c);
    setRow(r);
}

void Rectangle::resetRowAndColumn(int row, int column){
    setColumn(column);
    setRow(row);
}

bool Rectangle::inRect(float left, float top, float x, float y){
    if (y < BeginY + top || y > EndY + top) {
        return false;
    }
    if (x < BeginX + left || x > EndX + left) {
        return false;
    }
    return true;
}

float Rectangle::getPxY(double value) const {
    return (float) ( RectHeight - ((value - Min) / ZoomY + BeginY));
}

double Rectangle::getValueY(float px) const {
    return Min + (RectHeight - px + BeginY) * ZoomY;
}

int Rectangle::getViewIndexByPX(float px) const {
    px = (float) (Tools::between(BeginX, EndX, px));
    return (int) (round(Tools::between(0, RectWidth / ZoomX - 1, (px - BeginX) / ZoomX)));
}

float Rectangle::getViewPxByViewIndex(int dx) const {
    dx = (int) (Tools::between(0, RectWidth / ZoomX, dx));
    return round(BeginX + dx * ZoomX);
}

float Rectangle::getViewPxByViewIndexWithoutModify(int dx) const {
    return round(BeginX + dx * ZoomX);
}

int Rectangle::getDiffBetweenTwoPx(int x1, int x2) {
    return getViewIndexByPX(x2) - getViewIndexByPX(x1);
}

YTXPoint Rectangle::getInfoPosition(float x, float left, int width) const {
    float halfWidth = CanvasWidth / 2;
    if (x - left < halfWidth) {
        return ytxp(EndX - width, EndY);
    }
    return ytxp(BeginX, EndY);
}

void Rectangle::setRectanglePara(double max, double min)
{
    setMax(max);
    setMin(min);
    setZoomY(max, min);
}

void Rectangle::setColumnByRectHeight(int small, int middle, int big)
{
    switch (getHeightType()) {
        case SizeType::small:
            setColumn(small);
            break;
        case SizeType::middle:
            setColumn(middle);
            break;
        case SizeType::big:
            setColumn(big);
            break;
    }
}
